<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>任务调度系统</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css" rel="stylesheet">
    <style>
        .status-badge {
            font-size: 0.8em;
        }

        .task-card {
            transition: all 0.3s ease;
            border-left: 4px solid #dee2e6;
        }

        .task-card.pending {
            border-left-color: #6c757d;
        }

        .task-card.running {
            border-left-color: #0d6efd;
        }

        .task-card.completed {
            border-left-color: #198754;
        }

        .task-card.failed {
            border-left-color: #dc3545;
        }

        .task-card.cancelled {
            border-left-color: #fd7e14;
        }

        .stats-card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }

        .log-container {
            height: 300px;
            overflow-y: auto;
            background-color: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 0.375rem;
        }

        .log-entry {
            padding: 0.25rem 0.5rem;
            border-bottom: 1px solid #e9ecef;
        }

        .log-entry:last-child {
            border-bottom: none;
        }

        .navbar-brand {
            font-weight: bold;
        }

        /* 进度追踪样式 */
        .progress-container {
            margin-top: 20px;
        }

        .progress-item {
            margin: 10px 0;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 8px;
            background: #f9f9f9;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        .progress-bar-container {
            width: 100%;
            height: 24px;
            background: #e0e0e0;
            border-radius: 12px;
            overflow: hidden;
            margin: 10px 0;
            position: relative;
        }

        .progress-fill {
            height: 100%;
            background: linear-gradient(90deg, #4CAF50, #45a049);
            border-radius: 12px;
            transition: width 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 12px;
            font-weight: bold;
            min-width: 30px;
        }

        .task-info {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 8px;
        }

        .task-details {
            font-size: 12px;
            color: #666;
            margin-top: 8px;
        }

        .status-badge {
            padding: 4px 8px;
            border-radius: 12px;
            font-size: 11px;
            font-weight: bold;
            text-transform: uppercase;
        }

        .status-running {
            background: #2196F3;
            color: white;
        }

        .status-completed {
            background: #4CAF50;
            color: white;
        }

        .status-failed {
            background: #f44336;
            color: white;
        }

        .status-pending {
            background: #FF9800;
            color: white;
        }

        .status-cancelled {
            background: #9E9E9E;
            color: white;
        }
    </style>
</head>

<body class="bg-light">
    <!-- 导航栏 -->
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container-fluid">
            <a class="navbar-brand" href="#"><i class="bi bi-cpu"></i> 任务调度系统</a>
            <div class="navbar-nav ms-auto">
                <span class="navbar-text">
                    <span id="connection-status" class="badge bg-secondary">离线</span>
                </span>
            </div>
        </div>
    </nav>

    <div class="container-fluid mt-4">
        <div class="row">
            <!-- 左侧面板 -->
            <div class="col-lg-4">
                <!-- 创建任务表单 -->
                <div class="card mb-4">
                    <div class="card-header">
                        <h5 class="card-title mb-0"><i class="bi bi-plus-circle"></i> 创建任务</h5>
                    </div>
                    <div class="card-body">
                        <form id="task-form">
                            <div class="mb-3">
                                <label for="task-name" class="form-label">任务名称</label>
                                <input type="text" class="form-control" id="task-name" required>
                            </div>
                            <div class="mb-3">
                                <label for="task-type" class="form-label">任务类型</label>
                                <select class="form-select" id="task-type" required>
                                    <option value="light">轻度任务</option>
                                    <option value="heavy">重度任务</option>
                                    <option value="scheduled">定时任务</option>
                                    <option value="periodic">周期性任务</option>
                                </select>
                            </div>
                            <div class="mb-3">
                                <label for="func-name" class="form-label">执行函数</label>
                                <select class="form-select" id="func-name" required>
                                    <option value="">请选择函数</option>
                                </select>
                            </div>
                            <div class="mb-3">
                                <label for="task-priority" class="form-label">优先级</label>
                                <select class="form-select" id="task-priority">
                                    <option value="1">低</option>
                                    <option value="2" selected>中</option>
                                    <option value="3">高</option>
                                    <option value="4">紧急</option>
                                </select>
                            </div>
                            <!-- 定时任务相关字段 -->
                            <div id="schedule-fields" style="display: none;">
                                <div class="mb-3">
                                    <label for="schedule-time" class="form-label">执行时间</label>
                                    <input type="datetime-local" class="form-control" id="schedule-time">
                                </div>
                            </div>
                            <!-- 周期性任务相关字段 -->
                            <div id="periodic-fields" style="display: none;">
                                <div class="mb-3">
                                    <label for="interval" class="form-label">间隔时间(秒)</label>
                                    <input type="number" class="form-control" id="interval" min="1">
                                </div>
                            </div>
                            <button type="submit" class="btn btn-primary">
                                <i class="bi bi-play-fill"></i> 创建任务
                            </button>
                        </form>
                    </div>
                </div>

                <!-- 统计信息 -->
                <div class="card stats-card">
                    <div class="card-body">
                        <h5 class="card-title"><i class="bi bi-graph-up"></i> 系统统计</h5>
                        <div class="row text-center">
                            <div class="col-6 mb-3">
                                <div class="h3 mb-1" id="total-tasks">0</div>
                                <small>总任务数</small>
                            </div>
                            <div class="col-6 mb-3">
                                <div class="h3 mb-1" id="running-tasks">0</div>
                                <small>运行中</small>
                            </div>
                            <div class="col-6">
                                <div class="h3 mb-1" id="completed-tasks">0</div>
                                <small>已完成</small>
                            </div>
                            <div class="col-6">
                                <div class="h3 mb-1" id="failed-tasks">0</div>
                                <small>失败</small>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 系统日志 -->
                <div class="card mt-4">
                    <div class="card-header d-flex justify-content-between align-items-center">
                        <h6 class="mb-0"><i class="bi bi-journal-text"></i> 系统日志</h6>
                        <button class="btn btn-sm btn-outline-secondary" onclick="clearLogs()">
                            <i class="bi bi-trash"></i>
                        </button>
                    </div>
                    <div class="card-body p-0">
                        <div id="log-container" class="log-container p-2">
                            <!-- 日志条目将动态添加 -->
                        </div>
                    </div>
                </div>
            </div>

            <!-- 右侧面板 - 任务列表 -->
            <div class="col-lg-8">
                <div class="card">
                    <div class="card-header d-flex justify-content-between align-items-center">
                        <h5 class="card-title mb-0"><i class="bi bi-list-task"></i> 任务列表</h5>
                        <div>
                            <select class="form-select form-select-sm d-inline-block w-auto me-2" id="status-filter">
                                <option value="">所有状态</option>
                                <option value="pending">等待中</option>
                                <option value="running">运行中</option>
                                <option value="completed">已完成</option>
                                <option value="failed">失败</option>
                                <option value="cancelled">已取消</option>
                            </select>
                            <button class="btn btn-sm btn-outline-primary" onclick="refreshTasks()">
                                <i class="bi bi-arrow-clockwise"></i> 刷新
                            </button>
                        </div>
                    </div>
                    <div class="card-body">
                        <div id="tasks-container">
                            <!-- 任务卡片将动态添加 -->
                            <div class="text-center text-muted py-5">
                                <i class="bi bi-inbox" style="font-size: 3rem;"></i>
                                <p class="mt-3">暂无任务</p>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 实时进度追踪 -->
                <div class="card mt-4">
                    <div class="card-header">
                        <h5 class="card-title mb-0">
                            <i class="bi bi-activity"></i> 实时进度追踪
                            <span id="active-tasks-count" class="badge bg-primary ms-2">0</span>
                        </h5>
                    </div>
                    <div class="card-body">
                        <div id="progress-container">
                            <div class="text-center text-muted py-3">
                                <i class="bi bi-hourglass-split" style="font-size: 2rem;"></i>
                                <p class="mt-2">暂无运行中的任务</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // 全局变量
        let eventSource = null;
        let progressEventSource = null;
        let tasks = [];
        let stats = {};
        let activeTasks = new Map(); // 存储活跃任务的进度

        // 重连配置
        let reconnectAttempts = 0;
        let maxReconnectAttempts = 10;
        let baseReconnectDelay = 1000; // 1秒
        let progressReconnectAttempts = 0;

        // 连接状态
        let isConnecting = false;
        let isProgressConnecting = false;

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', function () {
            initializeApp();
        });

        // 页面卸载时清理资源
        window.addEventListener('beforeunload', function () {
            if (eventSource) {
                eventSource.close();
            }
            if (progressEventSource) {
                progressEventSource.close();
            }
        });

        // 页面隐藏时暂停连接，显示时恢复
        document.addEventListener('visibilitychange', function () {
            if (document.hidden) {
                console.log('页面已隐藏，暂停SSE连接');
            } else {
                console.log('页面已显示，检查SSE连接状态');
                // 检查连接状态并重连
                if (eventSource && eventSource.readyState === EventSource.CLOSED) {
                    connectSSE();
                }
                if (progressEventSource && progressEventSource.readyState === EventSource.CLOSED) {
                    connectProgressSSE();
                }
            }
        });

        // 初始化应用
        function initializeApp() {
            setupEventListeners();
            loadRegisteredFunctions();
            connectSSE();
            connectProgressSSE();
            refreshTasks();
            refreshStats();

            // 启动连接状态监控
            startConnectionMonitoring();
        }

        // 连接状态监控
        function startConnectionMonitoring() {
            setInterval(() => {
                // 检查主SSE连接
                if (eventSource && eventSource.readyState === EventSource.CLOSED && !isConnecting) {
                    console.log('检测到主SSE连接断开，尝试重连');
                    connectSSE();
                }

                // 检查进度SSE连接  
                if (progressEventSource && progressEventSource.readyState === EventSource.CLOSED && !isProgressConnecting) {
                    console.log('检测到进度SSE连接断开，尝试重连');
                    connectProgressSSE();
                }
            }, 10000); // 每10秒检查一次
        }

        // 连接进度追踪SSE
        function connectProgressSSE() {
            if (isProgressConnecting) {
                return; // 避免重复连接
            }

            isProgressConnecting = true;

            if (progressEventSource) {
                progressEventSource.close();
                progressEventSource = null;
            }

            try {
                progressEventSource = new EventSource('/api/v1/progress/stream');

                progressEventSource.onopen = function (event) {
                    console.log('进度追踪连接已建立');
                    progressReconnectAttempts = 0; // 重置重连次数
                    isProgressConnecting = false;
                };

                progressEventSource.addEventListener('task_progress', function (event) {
                    try {
                        const progressData = JSON.parse(event.data);
                        updateTaskProgress(progressData.data);
                    } catch (e) {
                        console.error('解析进度数据失败:', e);
                    }
                });

                progressEventSource.addEventListener('connected', function (event) {
                    try {
                        const data = JSON.parse(event.data);
                        console.log('进度追踪连接确认:', data.data.message);
                    } catch (e) {
                        console.error('解析连接确认数据失败:', e);
                    }
                });

                progressEventSource.addEventListener('heartbeat', function (event) {
                    // 进度追踪心跳 - 保持连接活跃
                    console.debug('收到进度追踪心跳');
                });

                progressEventSource.onerror = function (event) {
                    console.error('进度追踪连接错误:', event);
                    isProgressConnecting = false;

                    // 指数退避重连
                    if (progressReconnectAttempts < maxReconnectAttempts) {
                        const delay = Math.min(baseReconnectDelay * Math.pow(2, progressReconnectAttempts), 30000);
                        progressReconnectAttempts++;

                        console.log(`进度追踪将在 ${delay}ms 后重连 (第${progressReconnectAttempts}次尝试)`);

                        setTimeout(() => {
                            if (progressEventSource.readyState === EventSource.CLOSED) {
                                connectProgressSSE();
                            }
                        }, delay);
                    } else {
                        console.error('进度追踪连接重试次数已达上限，停止重连');
                        addLogEntry('进度追踪连接失败，请刷新页面重试', 'error');
                    }
                };

            } catch (error) {
                console.error('创建进度追踪SSE连接失败:', error);
                isProgressConnecting = false;
            }
        }

        // 更新任务进度
        function updateTaskProgress(progressData) {
            const taskId = progressData.task_id;
            activeTasks.set(taskId, progressData);
            renderTaskProgress(taskId, progressData);
            updateActiveTasksCount();
        }

        // 渲染任务进度
        function renderTaskProgress(taskId, data) {
            const container = document.getElementById('progress-container');
            let taskElement = document.getElementById(`progress-${taskId}`);

            if (!taskElement) {
                taskElement = createProgressElement(taskId);

                // 如果容器只有占位内容，先清空
                const placeholder = container.querySelector('.text-center.text-muted');
                if (placeholder) {
                    placeholder.remove();
                }

                container.appendChild(taskElement);
            }

            // 更新进度信息
            updateProgressElement(taskElement, data);

            // 如果任务完成或失败，延时移除
            if (data.status === 'completed' || data.status === 'failed') {
                setTimeout(() => {
                    if (taskElement.parentNode) {
                        taskElement.remove();
                        activeTasks.delete(taskId);
                        updateActiveTasksCount();

                        // 如果没有活跃任务了，显示占位内容
                        if (activeTasks.size === 0) {
                            showProgressPlaceholder();
                        }
                    }
                }, 5000);
            }
        }

        // 创建进度元素
        function createProgressElement(taskId) {
            const element = document.createElement('div');
            element.id = `progress-${taskId}`;
            element.className = 'progress-item';
            element.innerHTML = `
                <div class="task-info">
                    <span class="task-name fw-bold">任务 ${taskId}</span>
                    <span class="status-badge status-pending">pending</span>
                </div>
                <div class="progress-bar-container">
                    <div class="progress-fill" style="width: 0%">0%</div>
                </div>
                <div class="task-details">
                    <div class="row">
                        <div class="col-md-6">
                            <small><strong>状态:</strong> <span class="progress-message">等待中...</span></small><br>
                            <small><strong>步骤:</strong> <span class="progress-steps">0/0</span></small>
                        </div>
                        <div class="col-md-6">
                            <small><strong>开始时间:</strong> <span class="start-time">-</span></small><br>
                            <small><strong>预计剩余:</strong> <span class="eta-time">-</span></small>
                        </div>
                    </div>
                    <div class="subtasks-container mt-2"></div>
                </div>
            `;
            return element;
        }

        // 更新进度元素
        function updateProgressElement(element, data) {
            const taskName = element.querySelector('.task-name');
            const statusBadge = element.querySelector('.status-badge');
            const progressFill = element.querySelector('.progress-fill');
            const progressMessage = element.querySelector('.progress-message');
            const progressSteps = element.querySelector('.progress-steps');
            const startTime = element.querySelector('.start-time');
            const etaTime = element.querySelector('.eta-time');
            const subtasksContainer = element.querySelector('.subtasks-container');

            // 更新基本信息
            taskName.textContent = `任务 ${data.task_id}`;
            statusBadge.textContent = data.status;
            statusBadge.className = `status-badge status-${data.status}`;

            // 更新进度条
            const progress = Math.min(100, Math.max(0, data.progress || 0));
            progressFill.style.width = `${progress}%`;
            progressFill.textContent = `${progress.toFixed(1)}%`;

            // 更新详细信息
            progressMessage.textContent = data.message || '进行中...';
            progressSteps.textContent = `${data.steps_completed || 0}/${data.total_steps || 0}`;

            if (data.start_time) {
                const startDate = new Date(data.start_time);
                startTime.textContent = startDate.toLocaleTimeString();
            }

            if (data.eta && data.eta > 0) {
                const etaMinutes = Math.floor(data.eta / 60);
                const etaSeconds = Math.floor(data.eta % 60);
                etaTime.textContent = `${etaMinutes}分${etaSeconds}秒`;
            } else {
                etaTime.textContent = data.status === 'completed' ? '已完成' : '-';
            }

            // 更新子任务进度
            if (data.subtasks && Object.keys(data.subtasks).length > 0) {
                let subtasksHTML = '<div class="mt-2"><small><strong>子任务进度:</strong></small></div>';
                for (const [subtaskName, subtaskProgress] of Object.entries(data.subtasks)) {
                    subtasksHTML += `
                        <div class="d-flex justify-content-between align-items-center mt-1">
                            <small class="text-muted">${subtaskName}:</small>
                            <small class="fw-bold">${subtaskProgress.toFixed(1)}%</small>
                        </div>
                    `;
                }
                subtasksContainer.innerHTML = subtasksHTML;
            } else {
                subtasksContainer.innerHTML = '';
            }
        }

        // 显示进度占位内容
        function showProgressPlaceholder() {
            const container = document.getElementById('progress-container');
            container.innerHTML = `
                <div class="text-center text-muted py-3">
                    <i class="bi bi-hourglass-split" style="font-size: 2rem;"></i>
                    <p class="mt-2">暂无运行中的任务</p>
                </div>
            `;
        }

        // 更新活跃任务数量
        function updateActiveTasksCount() {
            const countElement = document.getElementById('active-tasks-count');
            countElement.textContent = activeTasks.size;

            if (activeTasks.size > 0) {
                countElement.className = 'badge bg-success ms-2';
            } else {
                countElement.className = 'badge bg-secondary ms-2';
            }
        }

        // 设置事件监听器
        function setupEventListeners() {
            // 任务表单提交
            document.getElementById('task-form').addEventListener('submit', handleTaskSubmit);

            // 任务类型变化
            document.getElementById('task-type').addEventListener('change', handleTaskTypeChange);

            // 状态筛选变化
            document.getElementById('status-filter').addEventListener('change', refreshTasks);
        }

        // 连接SSE
        function connectSSE() {
            if (isConnecting) {
                return; // 避免重复连接
            }

            isConnecting = true;

            // 清理现有连接
            if (eventSource) {
                eventSource.close();
                eventSource = null;
                // 短暂延迟确保连接完全关闭
                setTimeout(() => createConnection(), 100);
            } else {
                createConnection();
            }
        }

        function createConnection() {
            try {
                eventSource = new EventSource('/api/v1/sse/events');

                eventSource.onopen = function () {
                    updateConnectionStatus(true);
                    addLogEntry('已连接到服务器', 'success');
                    reconnectAttempts = 0; // 重置重连次数
                    isConnecting = false;
                };

                eventSource.onclose = function () {
                    console.log('SSE连接已关闭');
                    updateConnectionStatus(false);
                    isConnecting = false;
                };

                eventSource.onerror = function (event) {
                    console.error('SSE连接错误:', event);
                    updateConnectionStatus(false);
                    isConnecting = false;

                    // 立即关闭当前连接
                    if (eventSource) {
                        eventSource.close();
                        eventSource = null;
                    }

                    // 指数退避重连
                    if (reconnectAttempts < maxReconnectAttempts) {
                        const delay = Math.min(baseReconnectDelay * Math.pow(2, reconnectAttempts), 30000);
                        reconnectAttempts++;

                        addLogEntry(`连接失败，将在 ${delay / 1000}秒 后重连 (第${reconnectAttempts}次尝试)`, 'warning');

                        setTimeout(() => {
                            connectSSE();
                        }, delay);
                    } else {
                        addLogEntry('连接重试次数已达上限，请手动刷新页面', 'error');
                    }
                };

                eventSource.addEventListener('connected', function (event) {
                    try {
                        const data = JSON.parse(event.data);
                        addLogEntry(`已连接，客户端ID: ${data.data.client_id}`, 'info');
                    } catch (e) {
                        console.error('解析连接数据失败:', e);
                    }
                });

                eventSource.addEventListener('task_update', function (event) {
                    try {
                        const data = JSON.parse(event.data);
                        handleTaskUpdate(data.data);
                    } catch (e) {
                        console.error('解析任务更新数据失败:', e);
                    }
                });

                eventSource.addEventListener('progress_update', function (event) {
                    try {
                        const data = JSON.parse(event.data);
                        handleProgressUpdate(data.data);
                    } catch (e) {
                        console.error('解析进度更新数据失败:', e);
                    }
                });

                eventSource.addEventListener('system_message', function (event) {
                    try {
                        const data = JSON.parse(event.data);
                        addLogEntry(data.data.message, data.data.level || 'info');
                    } catch (e) {
                        console.error('解析系统消息失败:', e);
                    }
                });

                eventSource.addEventListener('heartbeat', function (event) {
                    // 心跳消息，保持连接活跃
                    console.debug('收到心跳');
                });

            } catch (error) {
                console.error('创建SSE连接失败:', error);
                isConnecting = false;
                updateConnectionStatus(false);
            }
        }

        // 更新连接状态
        function updateConnectionStatus(connected) {
            const statusElement = document.getElementById('connection-status');
            if (connected) {
                statusElement.textContent = '在线';
                statusElement.className = 'badge bg-success';
            } else {
                statusElement.textContent = '离线';
                statusElement.className = 'badge bg-danger';
            }
        }

        // 加载已注册的函数
        async function loadRegisteredFunctions() {
            try {
                const response = await fetch('/api/v1/functions');
                const data = await response.json();

                const funcSelect = document.getElementById('func-name');
                funcSelect.innerHTML = '<option value="">请选择函数</option>';

                data.functions.forEach(func => {
                    const option = document.createElement('option');
                    option.value = func.name;
                    option.textContent = `${func.name} (${func.type})`;
                    funcSelect.appendChild(option);
                });
            } catch (error) {
                console.error('加载函数列表失败:', error);
                addLogEntry('加载函数列表失败', 'error');
            }
        }

        // 处理任务类型变化
        function handleTaskTypeChange() {
            const taskType = document.getElementById('task-type').value;
            const scheduleFields = document.getElementById('schedule-fields');
            const periodicFields = document.getElementById('periodic-fields');

            // 隐藏所有特殊字段
            scheduleFields.style.display = 'none';
            periodicFields.style.display = 'none';

            // 根据任务类型显示相应字段
            if (taskType === 'scheduled') {
                scheduleFields.style.display = 'block';
            } else if (taskType === 'periodic') {
                periodicFields.style.display = 'block';
            }
        }

        // 处理任务表单提交
        async function handleTaskSubmit(event) {
            event.preventDefault();

            const formData = new FormData(event.target);
            const taskData = {
                name: document.getElementById('task-name').value,
                type: document.getElementById('task-type').value,
                func_name: document.getElementById('func-name').value,
                priority: parseInt(document.getElementById('task-priority').value),
                args: [],
                kwargs: {}
            };

            // 处理调度相关字段
            if (taskData.type === 'scheduled') {
                const scheduleTime = document.getElementById('schedule-time').value;
                if (scheduleTime) {
                    taskData.schedule_time = new Date(scheduleTime).toISOString();
                }
            } else if (taskData.type === 'periodic') {
                const interval = document.getElementById('interval').value;
                if (interval) {
                    taskData.interval = parseInt(interval);
                }
            }

            try {
                const response = await fetch('/api/v1/tasks', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(taskData)
                });

                if (response.ok) {
                    const task = await response.json();
                    addLogEntry(`任务已创建: ${task.name}`, 'success');
                    document.getElementById('task-form').reset();
                    handleTaskTypeChange(); // 重置字段显示
                } else {
                    const error = await response.json();
                    addLogEntry(`创建任务失败: ${error.detail}`, 'error');
                }
            } catch (error) {
                console.error('创建任务失败:', error);
                addLogEntry('创建任务失败: 网络错误', 'error');
            }
        }

        // 刷新任务列表
        async function refreshTasks() {
            try {
                const statusFilter = document.getElementById('status-filter').value;
                let url = '/api/v1/tasks?limit=50';
                if (statusFilter) {
                    url += `&status=${statusFilter}`;
                }

                const response = await fetch(url);
                const taskList = await response.json();

                tasks = taskList;
                renderTasks();
                refreshStats();
            } catch (error) {
                console.error('获取任务列表失败:', error);
                addLogEntry('获取任务列表失败', 'error');
            }
        }

        // 渲染任务列表
        function renderTasks() {
            const container = document.getElementById('tasks-container');

            if (tasks.length === 0) {
                container.innerHTML = `
                    <div class="text-center text-muted py-5">
                        <i class="bi bi-inbox" style="font-size: 3rem;"></i>
                        <p class="mt-3">暂无任务</p>
                    </div>
                `;
                return;
            }

            container.innerHTML = tasks.map(task => `
                <div class="card task-card ${task.status} mb-3" id="task-${task.id}">
                    <div class="card-body">
                        <div class="d-flex justify-content-between align-items-start">
                            <div class="flex-grow-1">
                                <h6 class="card-title">${task.name}</h6>
                                <p class="card-text text-muted mb-2">
                                    <small>
                                        函数: ${task.func_name} | 
                                        类型: ${getTypeDisplay(task.type)} |
                                        优先级: ${getPriorityDisplay(task.priority)}
                                    </small>
                                </p>
                                <div class="mb-2">
                                    <span class="badge status-badge ${getStatusBadgeClass(task.status)}">
                                        ${getStatusDisplay(task.status)}
                                    </span>
                                    ${task.retry_count > 0 ? `<span class="badge bg-warning ms-1">重试 ${task.retry_count}</span>` : ''}
                                </div>
                                
                                <!-- 进度条 -->
                                ${task.status === 'running' || (task.progress !== null && task.progress !== undefined && task.progress > 0) ?
                    `<div class="progress mb-2" style="height: 6px;">
                                        <div class="progress-bar" id="progress-${task.id}" role="progressbar" 
                                             style="width: ${task.progress || 0}%" 
                                             aria-valuenow="${task.progress || 0}" aria-valuemin="0" aria-valuemax="100">
                                        </div>
                                    </div>
                                    <small class="text-muted" id="progress-text-${task.id}">
                                        ${task.progress !== null && task.progress !== undefined ? `进度: ${task.progress.toFixed(1)}%` : ''}
                                    </small>` : ''
                }
                                
                                ${task.error ? `<div class="alert alert-danger alert-sm py-1 px-2 mt-2 mb-0"><small>${task.error}</small></div>` : ''}
                                ${task.result !== null && task.result !== undefined ? `<div class="alert alert-success alert-sm py-1 px-2 mt-2 mb-0"><small>结果: ${JSON.stringify(task.result)}</small></div>` : ''}
                            </div>
                            <div class="ms-3">
                                ${task.status === 'pending' || task.status === 'running' ?
                    `<button class="btn btn-sm btn-outline-danger" onclick="cancelTask('${task.id}')">
                                        <i class="bi bi-x-circle"></i> 取消
                                    </button>` : ''
                }
                            </div>
                        </div>
                        <div class="row text-muted mt-2">
                            <div class="col-sm-4">
                                <small>创建: ${formatDateTime(task.created_at)}</small>
                            </div>
                            ${task.started_at ? `<div class="col-sm-4"><small>开始: ${formatDateTime(task.started_at)}</small></div>` : ''}
                            ${task.completed_at ? `<div class="col-sm-4"><small>完成: ${formatDateTime(task.completed_at)}</small></div>` : ''}
                        </div>
                    </div>
                </div>
            `).join('');
        }

        // 刷新统计信息
        async function refreshStats() {
            try {
                const response = await fetch('/api/v1/tasks/stats');
                stats = await response.json();

                document.getElementById('total-tasks').textContent =
                    Object.values(stats.task_counts).reduce((a, b) => a + b, 0);
                document.getElementById('running-tasks').textContent =
                    stats.task_counts.running || 0;
                document.getElementById('completed-tasks').textContent =
                    stats.task_counts.completed || 0;
                document.getElementById('failed-tasks').textContent =
                    stats.task_counts.failed || 0;
            } catch (error) {
                console.error('获取统计信息失败:', error);
            }
        }

        // 取消任务
        async function cancelTask(taskId) {
            try {
                const response = await fetch(`/api/v1/tasks/${taskId}`, {
                    method: 'DELETE'
                });

                if (response.ok) {
                    addLogEntry('任务已取消', 'success');
                } else {
                    const error = await response.json();
                    addLogEntry(`取消任务失败: ${error.detail}`, 'error');
                }
            } catch (error) {
                console.error('取消任务失败:', error);
                addLogEntry('取消任务失败: 网络错误', 'error');
            }
        }

        // 处理任务更新
        function handleTaskUpdate(taskData) {
            // 更新任务列表中的对应任务
            const index = tasks.findIndex(t => t.id === taskData.task_id);
            if (index >= 0) {
                // 更新现有任务
                Object.assign(tasks[index], {
                    status: taskData.status,
                    result: taskData.result,
                    error: taskData.error,
                    progress: taskData.progress
                });
            }

            // 重新渲染任务列表
            renderTasks();
            refreshStats();

            // 添加日志
            addLogEntry(`任务更新: ${taskData.name} -> ${getStatusDisplay(taskData.status)}`, 'info');
        }

        // 处理进度更新
        function handleProgressUpdate(progressData) {
            // 更新任务列表中的进度
            const index = tasks.findIndex(t => t.id === progressData.task_id);
            if (index >= 0) {
                tasks[index].progress = progressData.progress;
            }

            // 更新进度条（如果存在）
            const progressBar = document.getElementById(`progress-${progressData.task_id}`);
            const progressText = document.getElementById(`progress-text-${progressData.task_id}`);

            if (progressBar) {
                progressBar.style.width = `${progressData.progress}%`;
                progressBar.setAttribute('aria-valuenow', progressData.progress);
            }

            if (progressText) {
                let text = `进度: ${progressData.progress.toFixed(1)}%`;
                if (progressData.message) {
                    text += ` - ${progressData.message}`;
                }
                progressText.textContent = text;
            }

            // 如果任务卡片不存在进度条，重新渲染该任务卡片
            if (!progressBar && progressData.progress > 0) {
                renderTasks();
            }

            // 记录进度日志（仅记录重要进度点）
            if (progressData.progress % 25 === 0 || progressData.progress === 100) {
                const message = progressData.message ?
                    `任务 ${progressData.task_name} 进度: ${progressData.progress.toFixed(1)}% - ${progressData.message}` :
                    `任务 ${progressData.task_name} 进度: ${progressData.progress.toFixed(1)}%`;
                addLogEntry(message, 'info');
            }
        }

        // 添加日志条目
        function addLogEntry(message, level = 'info') {
            const logContainer = document.getElementById('log-container');
            const logEntry = document.createElement('div');
            logEntry.className = `log-entry text-${getLogLevelClass(level)}`;
            logEntry.innerHTML = `
                <small class="text-muted">${new Date().toLocaleTimeString()}</small>
                <span class="ms-2">${message}</span>
            `;

            logContainer.appendChild(logEntry);
            logContainer.scrollTop = logContainer.scrollHeight;

            // 限制日志条目数量
            const entries = logContainer.children;
            if (entries.length > 100) {
                logContainer.removeChild(entries[0]);
            }
        }

        // 清空日志
        function clearLogs() {
            document.getElementById('log-container').innerHTML = '';
        }

        // 辅助函数
        function getTypeDisplay(type) {
            const types = {
                'light': '轻度',
                'heavy': '重度',
                'scheduled': '定时',
                'periodic': '周期'
            };
            return types[type] || type;
        }

        function getPriorityDisplay(priority) {
            const priorities = {
                1: '低',
                2: '中',
                3: '高',
                4: '紧急'
            };
            return priorities[priority] || priority;
        }

        function getStatusDisplay(status) {
            const statuses = {
                'pending': '等待中',
                'running': '运行中',
                'completed': '已完成',
                'failed': '失败',
                'cancelled': '已取消',
                'retrying': '重试中'
            };
            return statuses[status] || status;
        }

        function getStatusBadgeClass(status) {
            const classes = {
                'pending': 'bg-secondary',
                'running': 'bg-primary',
                'completed': 'bg-success',
                'failed': 'bg-danger',
                'cancelled': 'bg-warning',
                'retrying': 'bg-info'
            };
            return classes[status] || 'bg-secondary';
        }

        function getLogLevelClass(level) {
            const classes = {
                'success': 'success',
                'error': 'danger',
                'warning': 'warning',
                'info': 'info'
            };
            return classes[level] || 'dark';
        }

        function formatDateTime(isoString) {
            return new Date(isoString).toLocaleString('zh-CN');
        }

        // 页面卸载时关闭SSE连接
        window.addEventListener('beforeunload', function () {
            if (eventSource) {
                eventSource.close();
            }
        });
    </script>
</body>

</html>